<template>
  <div class="trace-detail">
    <header class="mb-8">
      <div class="flex justify-between items-center">
        <h1 class="glow-text">链路详情</h1>
        <button @click="goBack" class="btn btn-outline">返回</button>
      </div>
      <div class="tech-line mt-2"></div>
    </header>

    <div v-if="loading" class="flex justify-center items-center py-16">
      <div class="animate-spin rounded-full h-12 w-12 border-t-2 border-b-2 border-primary"></div>
    </div>

    <div v-else-if="!trace" class="text-center py-16 text-light-dark">
      未找到链路数据
    </div>

    <div v-else>
      <div class="mb-6">
        <h3 class="text-lg font-medium mb-2">基本信息</h3>
        <div class="card bg-dark-darker p-4">
          <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
            <div>
              <div class="text-light-dark mb-1">链路 ID:</div>
              <div class="font-mono">{{ trace._id }}</div>
            </div>
            <div>
              <div class="text-light-dark mb-1">创建时间:</div>
              <div>{{ formatDate(trace.created_at) }}</div>
            </div>
          </div>
        </div>
      </div>

      <div class="mb-6">
        <h3 class="text-lg font-medium mb-2">请求定义</h3>
        <div class="card bg-dark-darker p-4 font-mono text-sm overflow-x-auto">
          <pre>{{ JSON.stringify(trace.request_definition, null, 2) }}</pre>
        </div>
      </div>

      <div class="mb-6">
        <h3 class="text-lg font-medium mb-2">服务拓扑</h3>
        <div class="card bg-dark-darker p-4 h-64" ref="topologyContainer">
          <!-- 拓扑图将在这里渲染 -->
          <div v-show="loadingTopology" class="flex justify-center items-center h-full">
            <div class="animate-spin rounded-full h-8 w-8 border-t-2 border-b-2 border-primary"></div>
          </div>
          <div v-if="!topology.length" class="flex justify-center items-center h-full text-light-dark">
            暂无拓扑数据
          </div>
        </div>
      </div>

      <div class="mb-6">
        <h3 class="text-lg font-medium mb-2">服务列表</h3>
        <div class="card bg-dark-darker p-4">
          <div v-if="loadingServices" class="flex justify-center items-center py-8">
            <div class="animate-spin rounded-full h-8 w-8 border-t-2 border-b-2 border-primary"></div>
          </div>
          <div v-else-if="!services.length" class="text-center py-8 text-light-dark">
            暂无服务数据
          </div>
          <div v-else class="overflow-x-auto">
            <table class="w-full">
              <thead>
                <tr class="border-b border-dark">
                  <th class="py-2 px-4 text-left">服务 ID</th>
                  <th class="py-2 px-4 text-left">服务名称</th>
                  <th class="py-2 px-4 text-left">操作</th>
                </tr>
              </thead>
              <tbody>
                <tr
                  v-for="service in services"
                  :key="service._id"
                  class="border-b border-dark"
                >
                  <td class="py-2 px-4 font-mono text-sm">{{ service._id }}</td>
                  <td class="py-2 px-4">{{ service.service_name }}</td>
                  <td class="py-2 px-4">
                    <button
                      @click="viewServiceRequests(service._id)"
                      class="text-primary hover:text-primary-light"
                    >
                      查看请求
                    </button>
                  </td>
                </tr>
              </tbody>
            </table>
          </div>
        </div>
      </div>

      <div v-if="selectedService" class="mb-6">
        <h3 class="text-lg font-medium mb-2">服务请求信息</h3>
        <div class="card bg-dark-darker p-4">
          <div v-if="loadingRequests" class="flex justify-center items-center py-8">
            <div class="animate-spin rounded-full h-8 w-8 border-t-2 border-b-2 border-primary"></div>
          </div>
          <div v-else>
            <div class="mb-6">
              <h4 class="text-md font-medium mb-2">入口请求 (Ingress)</h4>
              <div v-if="!serviceRequests.ingress || !serviceRequests.ingress.length" class="text-light-dark">
                暂无入口请求
              </div>
              <div v-else>
                <div v-for="(request, index) in serviceRequests.ingress" :key="index" class="request-item border-b border-dark py-2">
                  <div class="flex items-center">
                    <span
                      class="badge mr-2"
                      :class="getMethodClass(request.method)"
                    >
                      {{ request.method || 'UNKNOWN' }}
                    </span>
                    <span class="font-mono text-sm break-all">{{ request.url || '' }}</span>
                  </div>
                </div>
              </div>
            </div>

            <div>
              <h4 class="text-md font-medium mb-2">出口请求 (Egress)</h4>
              <div v-if="!serviceRequests.egress || !serviceRequests.egress.length" class="text-light-dark">
                暂无出口请求
              </div>
              <div v-else>
                <div v-for="(request, index) in serviceRequests.egress" :key="index" class="request-item border-b border-dark py-2">
                  <div class="flex items-center">
                    <span
                      class="badge mr-2"
                      :class="getMethodClass(request.method)"
                    >
                      {{ request.method || 'UNKNOWN' }}
                    </span>
                    <span class="font-mono text-sm break-all">{{ request.url || '' }}</span>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, nextTick } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { tracesApi } from '../api';
// 移除 G6 导入，因为我们将使用更简单的方式渲染拓扑图

// 定义类型
interface Trace {
  _id: string;
  request_definition: any;
  trace_data: any[];
  service_count: number;
  span_count: number;
  created_at: string;
  updated_at: string;
}

interface Service {
  _id: string;
  trace_id: string;
  service_name: string;
  created_at: string;
}

interface TopologyLink {
  source: string;
  target: string;
}

interface Request {
  _id: string;
  service_id: string;
  request_type: 'ingress' | 'egress';
  method: string;
  url: string;
  created_at: string;
}

interface ServiceRequests {
  ingress: Request[];
  egress: Request[];
}

// 路由相关
const route = useRoute();
const router = useRouter();
const traceId = route.params.id as string;

// 状态变量
const loading = ref(false);
const trace = ref<Trace | null>(null);
const loadingTopology = ref(false);
const topology = ref<TopologyLink[]>([]);
const loadingServices = ref(false);
const services = ref<Service[]>([]);
const selectedService = ref<string | null>(null);
const loadingRequests = ref(false);
const serviceRequests = ref<ServiceRequests>({
  ingress: [],
  egress: []
});

// 拓扑图容器引用
const topologyContainer = ref<HTMLElement | null>(null);

// 获取链路详情
const fetchTraceDetail = async () => {
  try {
    loading.value = true;
    const response = await tracesApi.getById(traceId);
    trace.value = response.data || response;

    // 获取服务列表
    await fetchServices();

    // 获取拓扑关系
    fetchTopology();
  } catch (error: any) {
    console.error('获取链路详情失败:', error);
  } finally {
    loading.value = false;
  }
};

// 获取服务列表
const fetchServices = async () => {
  try {
    loadingServices.value = true;
    const response = await tracesApi.getServices(traceId);
    services.value = response.data || response;
  } catch (error: any) {
    console.error('获取服务列表失败:', error);
  } finally {
    loadingServices.value = false;
  }
};

// 获取拓扑关系
const fetchTopology = async () => {
  try {
    loadingTopology.value = true;
    const response = await tracesApi.getTopology(traceId);
    topology.value = response.data || response;

    // 在下一个 tick 渲染拓扑图
    await nextTick();
    renderTopology();
  } catch (error: any) {
    console.error('获取拓扑关系失败:', error);
  } finally {
    loadingTopology.value = false;
  }
};

// 查看服务请求
const viewServiceRequests = async (serviceId: string) => {
  if (!serviceId) return;

  try {
    // 设置状态
    loadingRequests.value = true;
    selectedService.value = serviceId;

    // 重置数据
    serviceRequests.value = { ingress: [], egress: [] };

    // 等待一个帧
    await new Promise(resolve => setTimeout(resolve, 0));

    // 请求数据
    const response = await tracesApi.getServiceRequests(serviceId);

    // 处理数据
    if (response && typeof response === 'object') {
      const data = response as any;
      serviceRequests.value = {
        ingress: Array.isArray(data.ingress) ? data.ingress : [],
        egress: Array.isArray(data.egress) ? data.egress : []
      };
    }
  } catch (error: any) {
    console.error('获取服务请求失败:', error);
  } finally {
    loadingRequests.value = false;
  }
};

// 渲染拓扑图
const renderTopology = () => {
  if (!topologyContainer.value || !topology.value.length) return;

  const container = topologyContainer.value;
  container.innerHTML = '';

  // 创建 SVG 元素
  const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
  svg.setAttribute('width', '100%');
  svg.setAttribute('height', '100%');
  svg.style.overflow = 'visible';

  // 准备数据
  const nodeIds = new Set<string>();
  topology.value.forEach(link => {
    nodeIds.add(link.source);
    nodeIds.add(link.target);
  });

  // 创建节点映射
  const nodeList = Array.from(nodeIds);
  const nodeMap = new Map<string, { id: string, name: string, x: number, y: number }>();

  // 从服务列表中获取服务名称
  const serviceNameMap = new Map<string, string>();
  services.value.forEach(service => {
    serviceNameMap.set(service._id, service.service_name);
  });

  // 计算节点位置（圆形布局）
  const radius = Math.min(container.clientWidth, container.clientHeight) / 2 - 50;
  const centerX = container.clientWidth / 2;
  const centerY = container.clientHeight / 2;

  nodeList.forEach((id, index) => {
    const angle = (index / nodeList.length) * 2 * Math.PI;
    const x = centerX + radius * Math.cos(angle);
    const y = centerY + radius * Math.sin(angle);
    const name = serviceNameMap.get(id) || id.substring(0, 8);

    nodeMap.set(id, { id, name, x, y });
  });

  // 绘制连线
  topology.value.forEach(link => {
    const source = nodeMap.get(link.source);
    const target = nodeMap.get(link.target);

    if (!source || !target || source===target) return;

    // 创建连线
    const line = document.createElementNS('http://www.w3.org/2000/svg', 'line');
    line.setAttribute('x1', source.x.toString());
    line.setAttribute('y1', source.y.toString());
    line.setAttribute('x2', target.x.toString());
    line.setAttribute('y2', target.y.toString());
    line.setAttribute('stroke', '#3b82f6');
    line.setAttribute('stroke-width', '2');
    svg.appendChild(line);

    // 创建箭头
    const dx = target.x - source.x;
    const dy = target.y - source.y;
    const angle = Math.atan2(dy, dx);

    const arrowSize = 10;
    const arrowX = target.x - 20 * Math.cos(angle);
    const arrowY = target.y - 20 * Math.sin(angle);

    const arrow = document.createElementNS('http://www.w3.org/2000/svg', 'polygon');
    arrow.setAttribute('points', `
      ${arrowX},${arrowY}
      ${arrowX - arrowSize * Math.cos(angle - Math.PI/6)},${arrowY - arrowSize * Math.sin(angle - Math.PI/6)}
      ${arrowX - arrowSize * Math.cos(angle + Math.PI/6)},${arrowY - arrowSize * Math.sin(angle + Math.PI/6)}
    `);
    arrow.setAttribute('fill', '#3b82f6');
    svg.appendChild(arrow);
  });

  // 绘制节点
  nodeMap.forEach(node => {
    // 创建节点圆圈
    const circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
    circle.setAttribute('cx', node.x.toString());
    circle.setAttribute('cy', node.y.toString());
    circle.setAttribute('r', '20');
    circle.setAttribute('fill', '#1f2937');
    circle.setAttribute('stroke', '#3b82f6');
    circle.setAttribute('stroke-width', '2');
    svg.appendChild(circle);

    // 创建节点文本
    const text = document.createElementNS('http://www.w3.org/2000/svg', 'text');
    text.setAttribute('x', node.x.toString());
    text.setAttribute('y', (node.y + 35).toString());
    text.setAttribute('text-anchor', 'middle');
    text.setAttribute('fill', '#e5e7eb');
    text.setAttribute('font-size', '12');
    text.textContent = node.name;
    svg.appendChild(text);
  });

  container.appendChild(svg);
};

// 格式化日期
const formatDate = (dateString: string) => {
  if (!dateString) return '';
  const date = new Date(dateString);
  return date.toLocaleString('zh-CN');
};

// 获取方法对应的样式类
const getMethodClass = (method: string) => {
  if (!method) return 'badge-yellow';

  switch(method.toUpperCase()) {
    case 'GET': return 'badge-blue';
    case 'POST': return 'badge-green';
    case 'PUT': return 'badge-purple';
    case 'DELETE': return 'badge-orange';
    default: return 'badge-yellow';
  }
};

// 返回上一页
const goBack = () => {
  router.push('/traces');
};

// 组件挂载时获取数据
onMounted(() => {
  fetchTraceDetail();

  // 监听窗口大小变化，重新渲染拓扑图
  window.addEventListener('resize', () => {
    if (topologyContainer.value && topology.value.length > 0) {
      renderTopology();
    }
  });
});
</script>

<style scoped>
.request-item:last-child {
  border-bottom: none;
}
</style>
